{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d197452b",
   "metadata": {},
   "source": [
    "This notebook showcases `MosaicWidget`'s interoperability with various dataframe libraries. Leveraging [Narwhals](https://github.com/narwhals-dev/narwhals) as an abstraction layer, `MosaicWidget` accepts data from backends like Pandas, Polars, Dask, Modin, PyArrow tables, and DuckDB relations without requiring manual conversion."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "423632ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Install dataframe libs not part of Mosaic dependencies\n",
    "!uv pip install dask ibis-framework pyarrow-hotfix modin polars -q"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "dc4f8649",
   "metadata": {},
   "outputs": [],
   "source": [
    "import dask.dataframe as dd\n",
    "import duckdb\n",
    "import ibis\n",
    "import modin.pandas as md\n",
    "import pandas as pd\n",
    "import polars as pl\n",
    "import pyarrow as pa\n",
    "\n",
    "import yaml\n",
    "from mosaic_widget import MosaicWidget\n",
    "\n",
    "from IPython.display import display, Markdown"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "88e82e94",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Mandatory Modin configuration\n",
    "import os\n",
    "\n",
    "os.environ[\"MODIN_ENGINE\"] = \"python\"\n",
    "os.environ[\"MODIN_STORAGE_FORMAT\"] = \"pandas\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d8d26209",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Optional: enable logging in Mosaic widget to get informed about dataset conversion details\n",
    "import logging\n",
    "\n",
    "logging.basicConfig(level=logging.WARN)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6b32364b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load weather spec, remove data key to ensure load from demonstrated backends\n",
    "with open(\"../../specs/yaml/weather.yaml\") as f:\n",
    "    spec = yaml.safe_load(f)\n",
    "    spec.pop(\"data\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "a5f9ac94",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "UserWarning: `read_csv` is not currently supported by PandasOnPython, defaulting to pandas implementation.\n",
      "Please refer to https://modin.readthedocs.io/en/stable/supported_apis/defaulting_to_pandas.html for explanation.\n"
     ]
    }
   ],
   "source": [
    "csv_path = \"../../data/seattle-weather.csv\"\n",
    "\n",
    "weather_dd = dd.read_csv(csv_path, parse_dates=[\"date\"])\n",
    "weather_duckdb = duckdb.query(f\"select * from '{csv_path}'\")\n",
    "weather_ibis = ibis.read_csv(csv_path)\n",
    "weather_modin = md.read_csv(csv_path, parse_dates=[\"date\"])\n",
    "weather_pd = pd.read_csv(csv_path, parse_dates=[\"date\"])\n",
    "weather_pa = pa.Table.from_pandas(weather_pd)\n",
    "weather_pl = pl.read_csv(csv_path, try_parse_dates=True)\n",
    "\n",
    "datasets = [\n",
    "    # Native\n",
    "    weather_pd,\n",
    "    weather_pl,\n",
    "    weather_pa,\n",
    "    # Eager\n",
    "    weather_modin,\n",
    "    # Lazy\n",
    "    weather_dd,\n",
    "    weather_ibis,\n",
    "    weather_duckdb,\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "729bf911",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "### Mosaic Widget with data from `pandas.core.frame.DataFrame` backend"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "aaefa63fc4b44d2eb4971a580ee4bd6b",
       "version_major": 2,
       "version_minor": 1
      },
      "text/plain": [
       "MosaicWidget(spec={'meta': {'title': 'Seattle Weather', 'description': \"An interactive view of Seattle's weath…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "### Mosaic Widget with data from `polars.dataframe.frame.DataFrame` backend"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7c113b7ef67d414ea941f760e0d8cc69",
       "version_major": 2,
       "version_minor": 1
      },
      "text/plain": [
       "MosaicWidget(spec={'meta': {'title': 'Seattle Weather', 'description': \"An interactive view of Seattle's weath…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "### Mosaic Widget with data from `pyarrow.lib.Table` backend"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "0ef94810b68949668db370adb6416768",
       "version_major": 2,
       "version_minor": 1
      },
      "text/plain": [
       "MosaicWidget(spec={'meta': {'title': 'Seattle Weather', 'description': \"An interactive view of Seattle's weath…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "### Mosaic Widget with data from `modin.pandas.dataframe.DataFrame` backend"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:mosaic_widget.frame_interop:Converting <class 'modin.pandas.dataframe.DataFrame'> to Arrow table for DuckDB registration. This may not be a zero-copy operation.\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e04608b4b9bf4b529b3e162f9cd87892",
       "version_major": 2,
       "version_minor": 1
      },
      "text/plain": [
       "MosaicWidget(spec={'meta': {'title': 'Seattle Weather', 'description': \"An interactive view of Seattle's weath…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "### Mosaic Widget with data from `dask.dataframe.dask_expr._collection.DataFrame` backend"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:mosaic_widget.frame_interop:Converting <class 'dask.dataframe.dask_expr._collection.DataFrame'> to Arrow table for DuckDB registration. This may not be a zero-copy operation.\n",
      "WARNING:mosaic_widget.frame_interop:Materializing lazy frame\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "0ac1273ec48e4b6c9c75ca02c927208f",
       "version_major": 2,
       "version_minor": 1
      },
      "text/plain": [
       "MosaicWidget(spec={'meta': {'title': 'Seattle Weather', 'description': \"An interactive view of Seattle's weath…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "### Mosaic Widget with data from `ibis.expr.types.relations.Table` backend"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:mosaic_widget.frame_interop:Converting <class 'ibis.expr.types.relations.Table'> to Arrow table for DuckDB registration. This may not be a zero-copy operation.\n",
      "WARNING:mosaic_widget.frame_interop:Materializing lazy frame\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "faba7fc6ec8d49dca9348b10dee8c860",
       "version_major": 2,
       "version_minor": 1
      },
      "text/plain": [
       "MosaicWidget(spec={'meta': {'title': 'Seattle Weather', 'description': \"An interactive view of Seattle's weath…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "### Mosaic Widget with data from `duckdb.duckdb.DuckDBPyRelation` backend"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:mosaic_widget.frame_interop:Converting <class 'duckdb.duckdb.DuckDBPyRelation'> to Arrow table for DuckDB registration. This may not be a zero-copy operation.\n",
      "WARNING:mosaic_widget.frame_interop:Materializing lazy frame\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "403f1f1358e1485b9b125c8e4a18cd4f",
       "version_major": 2,
       "version_minor": 1
      },
      "text/plain": [
       "MosaicWidget(spec={'meta': {'title': 'Seattle Weather', 'description': \"An interactive view of Seattle's weath…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for dataset in datasets:\n",
    "    backend_name = str(type(dataset))[8:-2]\n",
    "    display(Markdown(f\"### Mosaic Widget with data from `{backend_name}` backend\"))\n",
    "    display(MosaicWidget(spec, data={\"weather\": dataset}))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
